using System;
using System.IO;

namespace NMock2.Matchers
{
	/// <summary>
	/// Matches 2 objects using IComparable
	/// <para><span style="color:red;font-weight:bold;">This class is new to NMock3.</span></para>
	/// </summary>
	public class ObjectMatcher : Matcher
	{
		private object _o;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="o"></param>
		public ObjectMatcher(object o)
		{
			_o = o;	
		}

		/// <summary>
		/// Compares 2 objects using IComparable
		/// </summary>
		/// <param name="o"></param>
		/// <returns></returns>
		public override bool Matches(object o)
		{
			if(o == null)
				throw new ArgumentNullException("o");

			if(_o == null)
				throw new InvalidOperationException("The object of comparison is null.");

			if(o as IComparable == null)
				throw new InvalidOperationException(string.Format("The object being compared does not support IComparable.  Type: {0}", o.GetType()));

			if(_o as IComparable == null)
				throw new InvalidOperationException(string.Format("The object of comparison does not support IComparable.  Type: {0}", _o.GetType()));

			return ((IComparable)_o).CompareTo(o) == 0;
		}

		/// <summary>
		/// Describes a mismatch
		/// </summary>
		/// <param name="writer"></param>
		public override void DescribeTo(TextWriter writer)
		{
			if(_o == null)
				writer.Write("Object in ObjectMatcher is null.");

			writer.Write(_o.ToString());
		}
	}

	/// <summary>
	/// Syntax class
	/// </summary>
	public class Comparable
	{
		/// <summary>
		/// Returns an object matcher
		/// </summary>
		/// <param name="o"></param>
		/// <returns></returns>
		public static Matcher To(object o)
		{
			if(o == null)
				throw new ArgumentNullException("o", "A null object was passed to the Comparable.To method.");

			return new ObjectMatcher(o);
		}
	}
}